﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
namespace AccountingLibrary
{
   public abstract class ClosingAccountingBase
    {
       private AccountingPeriods current;
       private ClosingSetting setting;
       private IAccountable allaccounts;
       public ClosingAccountingBase( AccountingPeriods per,ClosingSetting closing_setting)
       {
           this.current = per;
           this.setting = closing_setting;
           
       }
     public  bool close_it(string[]temp,IAccountable accounts)
       {
           this.allaccounts = accounts;
           try
           {
               end_current();
               start_new();
               close_journals(temp);
               return true;
           }
           catch 
           {
               return false;

           }
       }
       //نهاية الفترة المحاسبية
       void end_current()
       {
           current.State =(int)PeriodsState.Ended;
           Save_AccountP(current);

       }
    
       //بداية الفترة المحاسبية
       void start_new()
       {
           AccountingPeriods newper = new AccountingPeriods();
           newper.Start = current.End.AddDays(1);
           newper.End = (current.End.AddDays(1)).AddMonths((int)setting.MonthPeriod);
           newper.State = (int)PeriodsState.Running;
           Save_AccountP(newper);
       }
     protected abstract bool  Save_AccountP(AccountingPeriods periods);
     public void close_journals(string[] temprory_accounts_type)
       {
           var accountlist = allaccounts.get_accounts();

           foreach (AccountBase acco in accountlist)
           {
             foreach(string s in temprory_accounts_type){
                 if (acco.main == s)reset_temp(acco);
                 else last_2_frist(acco);
             }
           }
       }
     private void reset_temp( AccountBase temp_account)
     {
       
             AccountDetail closed_account = new AccountDetail()
             {
                 account_id = temp_account.id,
                 frist_value = 0,
                 frist_value_date = current.End.AddDays(1)
             };
             save_account_details(closed_account);
         
     }
     private void last_2_frist(AccountBase fixed_account)
     {
         //two query ::
     
         AccountDetail closed_account = new AccountDetail()
         {
             account_id = fixed_account.id,
             frist_value_date = current.End.AddDays(1),
             frist_value = get_last(fixed_account)
         };
         save_account_details(closed_account);
     }
       protected abstract  double get_last(AccountBase fix_account);
       protected abstract bool save_account_details(AccountDetail detail);

    }
}
